import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;

import kisti.lod.sindice.MySindice;
import kisti.lod.sindice.TooManyRequestsException;
import kisti.lod.sindice.query.LiveQuery;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.sindice.SindiceException;
import com.sindice.query.CacheQuery;
import com.sindice.result.CacheResult;


public class SindiceTest {
	
	public static final String LIVE_API = "live_api";
	public static final String CACHE_API = "cache_api";
	
	protected static MySindice sindice = new MySindice();
	protected static LiveQuery liveQuery = new LiveQuery();
	
	protected static String apiType = CACHE_API;
	
	public static void main(String[] args) throws SocketTimeoutException, SindiceException {

		Model tmpModel = ModelFactory.createDefaultModel();
		
		String subjectUri = "http://dbpedia.org/resource/Aster_Data_Systems";
		
		StringBuffer sindiceTriples = getTriples(subjectUri);
		if(sindiceTriples == null) {
			throw new SindiceException("No triples returned!");
		}
		System.out.println(sindiceTriples);
		
		//convert string to input stream for jena to parse
		byte[] bytes;
		//try to convert to utf-8
		try {
			bytes = sindiceTriples.toString().getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
		//if conversion fails, replace every non utf-8 char with a questionmark
			String triples = sindiceTriples.toString();
			triples.replaceAll("[^(\\x20-\\x7F)]", "?");
			bytes = triples.getBytes();
		}
		InputStream is = new ByteArrayInputStream(bytes);
		tmpModel.read(is, null, "N-TRIPLE"); //parse N-Triples using JENA
		
		tmpModel.write(System.out);
	}
	
	
	public static StringBuffer getTriples(String subjectUri) throws SindiceException, SocketTimeoutException {
		StringBuffer tripleBuffer = new StringBuffer();
		if(apiType == CACHE_API) {
			//query for explicit triples using sindice
			CacheQuery cacheQuery = new CacheQuery(subjectUri);
			CacheResult cacheResult = sindice.cacheQuery(cacheQuery);
			String[] triples = cacheResult.getExplicitContent();
			
			if(triples.length == 0) {
				return null;
			}
			
			//append all triples to string buffer
			for(int z=0;z<triples.length;z++) {
				tripleBuffer.append((triples[z]));
			}
			return tripleBuffer;
		}
		else {
			try {
				tripleBuffer = liveQuery.performQuery(subjectUri);
			}
			//if querying fails due to too many requests, sleep for 3 seconds and try again
			catch (TooManyRequestsException e) {
				try {
					Thread.sleep(3000);
				}
				catch (InterruptedException ie) {
				}
				tripleBuffer = liveQuery.performQuery(subjectUri);
				return tripleBuffer;
			}
			return tripleBuffer;
		}
	}
}
